#ifndef DODO_OUTPUT_LIDARPRO_H
#define DODO_OUTPUT_LIDARPRO_H

#include <iostream>
#include <fstream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <stdexcept>
#include <string>
#include <algorithm>

namespace quigon
{

class Output_Lidarpro
{
public:	
	Output_Lidarpro(std::ostream &file_stream0, size_t zero_meter_index0) : 
		file(file_stream0), rec_num(0), zero_meter_index(zero_meter_index0) 
	{
	}

	Output_Lidarpro(const std::string &file_name, size_t zero_meter_index0) : 
		file(file_impl), rec_num(0), zero_meter_index(zero_meter_index0) 
	{
		file_impl.open(file_name.c_str());
		if(!file_impl)
		{
			std::cerr << "Output_Lidarpro : Can't open file to write: " << file_name << std::endl;
			throw std::invalid_argument(std::string("file_name: ") + file_name);
		}
	}

	Output_Lidarpro(const boost::posix_time::ptime &t1, const boost::posix_time::ptime &t2, 
		const std::string& prefix, const std::string& ext, 
		size_t zero_meter_index0) : 
		file(file_impl), rec_num(0), zero_meter_index(zero_meter_index0) 
	{
		std::string time_str = boost::posix_time::to_iso_string(t1) + "_" + boost::posix_time::to_iso_string(t2);
		std::string::iterator str_iter = remove(time_str.begin(), time_str.end(), 'T');
		time_str.erase(str_iter, time_str.end());
		std::string file_name = prefix + "_" + time_str + "." + ext;

		file_impl.open(file_name.c_str());
		if(!file_impl)
		{
			std::cerr << "Output_Lidarpro : Can't open file to write: " << file_name << std::endl;
			throw std::invalid_argument(std::string("file_name: ") + file_name);
		}
	}

	Output_Lidarpro(const std::string& t1_str, const std::string& t2_str, 
                const std::string& prefix, const std::string& ext, 
                size_t zero_meter_index0) : 
		file(file_impl), rec_num(0), zero_meter_index(zero_meter_index0) 
        {
                std::string time_str = t1_str + "_" + t2_str; 
                std::string::iterator str_iter = remove(time_str.begin(), time_str.end(), 'T');
                time_str.erase(str_iter, time_str.end());
                std::string file_name = prefix + "_" + time_str + "." + ext;

                file_impl.open(file_name.c_str());
                if(!file_impl)
                {
                        std::cerr << "Output_Lidarpro : Can't open file to write: " << file_name << std::endl;
                        throw std::invalid_argument(std::string("file_name: ") + file_name);
                }
        }

	void reset() { rec_num = 0; }

	template<class Tline>
	bool operator()(const Tline& line)
	{
		using namespace std;
		using namespace boost::posix_time;
		using namespace boost::gregorian;

		date d = line.t().date();
		time_duration tod = line.t().time_of_day();

		file << d.year() << "\t" << d.month().as_number() << "\t" << d.day() ;
		file << "\t\t" << tod.hours() << "\t" << tod.minutes() << "\t" << tod.seconds() << endl;
		file << line["laser_freq"] << endl;
		file << static_cast<long>(line.duration().total_milliseconds() * line["laser_freq"] / 1000 + 0.5) << endl;
		file << line["energy"] << endl;
		file << line["temp_detector"] << "\t" << line["temp_box"] << "\t" << line["temp_laser"] << endl;
		file << line["cbh"] << endl;
		file << line["background"] << endl;
		file << line["bin_time"] << endl;
		file << (line.size() - zero_meter_index) * line["bin_size"] * line["sin_elev_angle"] << endl;
		file << line["dtc"] << endl;
		file << rec_num << "\t" << line.size() - zero_meter_index ; // save the endl for the loop

		int count = 0;
		for (int i = zero_meter_index; i < line.size()  ; ++i)
		{

			if (count % 10 == 0)
				file << endl;
			file << line[i] << "\t";
			count ++;

		}

		file << endl;
		++ rec_num;
		return true;

	}

protected:
	std::ostream& file;
	std::ofstream file_impl;
	size_t rec_num;
	size_t zero_meter_index;
};

}

#endif

